use winit::dpi::LogicalSize;
use winit::window::Window;
use std::sync::Arc;
use std::cell::{RefCell};

mod pixels_draw;
mod gui;

#[derive(Default)]
pub struct App<'a> {
    win: Option<Arc<Window>>,
    // win: Box<Window>,
    pixels: Option<Arc<RefCell<pixels::Pixels<'a>>>>,
    scale: Option<f32>,
    win_size: winit::dpi::LogicalSize<f32>,
}

impl<'a> App<'a>{

}

impl<'a> winit::application::ApplicationHandler for App<'a>{
    fn resumed(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) {
        env_logger::init();

        let win_size = winit::dpi::LogicalSize::new(800.0, 600.0);
        
        let win = event_loop.create_window(
            winit::window::WindowAttributes::default()
            .with_title("winit_egui_pixels")
            .with_inner_size(win_size.clone())
            .with_min_inner_size(win_size.clone())
        ).unwrap();

        // let win_size: LogicalSize<f64> = win.inner_size().clone().to_logical(win.scale_factor().clone());
        
        
        let scale = win.scale_factor() as f32;

        self.scale = Some(scale);
        
        self.win = Some(Arc::new(win));
        let win = match &self.win {
            None => {
                event_loop.exit();
                return;
            }
            Some(win) => {
                win.clone()
            }
        };
        
        let surface_texture = pixels::SurfaceTexture::new(win_size.width.clone() as u32, win_size.height.clone() as u32,win);
        let mut pixels = pixels::Pixels::new(win_size.width.clone() as u32, win_size.height.clone() as u32, surface_texture).unwrap();
        
        pixels.set_present_mode(pixels::wgpu::PresentMode::Immediate);
        
        self.pixels = Some(Arc::new(RefCell::new(pixels)));  
        
        // let win = Box::new(win);
        // self.win = win.();
        
        // self.scale = win.scale_factor() as f32;
        
        
        // self.win = Some(win);
        // self.scale = win.as_ref().unwrap().scale_factor() as f32;

        // let win = self.win.as_ref().unwrap();

    }
    fn window_event(
            &mut self,
            event_loop: &winit::event_loop::ActiveEventLoop,
            _window_id: winit::window::WindowId,
            event: winit::event::WindowEvent,
        ) 
    {
    
        let pixels = match &self.pixels{
            None => {
                event_loop.exit();
                return;
            }
            Some(pixels) => {
                pixels.clone()
            }
        };

        let win = match &self.win{
            None => {
                event_loop.exit();
                return;
            }
            Some(win) => {
                win.clone()
            }
        };

        match event {

            winit::event::WindowEvent::Resized(size) => {
                // println!("{:?},{:?}",(&self.win_size.width,&self.win_size.height),(pixels.borrow().texture().width(),pixels.borrow().texture().height()));
                self.win_size = size.to_logical(win.scale_factor() as f64);
                win.request_redraw();
                pixels.borrow_mut().resize_surface(self.win_size.width.clone() as u32,self.win_size.height.clone() as u32).unwrap();
            }

            winit::event::WindowEvent::RedrawRequested => {



                pixels_draw::draw(&self.win_size, pixels.borrow_mut().frame_mut());

                let render_res = pixels.borrow_mut().render_with(|encoder,render_target,context|{
                    context.scaling_renderer.render(encoder, render_target);
                    Ok(())
                });

                if let Err(err) = render_res {
                    println!("{}",err.to_string());
                    event_loop.exit();
                    return;
                }
            }

            winit::event::WindowEvent::Destroyed => {
                event_loop.exit();
                return;
            }

            winit::event::WindowEvent::CloseRequested => {
                event_loop.exit();
                return;
            }

            _ => (),
        }

        
    }

}
